package com.itheima.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.google.common.collect.Lists;
import com.itheima.dto.LimitRulesDto;
import com.itheima.dto.ReginDto;
import com.itheima.dto.UserDTO;
import com.itheima.entity.ExcelModel;
import com.itheima.entity.Order;
import com.itheima.entity.OrderPark;
import com.itheima.entity.OrderParkDTO;
import com.itheima.mapper.OrderParkMapper;
import com.itheima.service.impl.UserPayServiceFactory;
import com.itheima.utils.FileUtils;

@Service
public class OrderService {

    @Autowired
    private OrderParkMapper orderParkMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    HttpServletRequest request;

    /**
     * 根据不同会员身份计算订单应收金额
     * 采用工厂 + 策略模式消除繁多的if else
     * @param orderPrice 订单原价
     * @return 折扣后的金额
     */
    public BigDecimal payPrice(BigDecimal orderPrice, Integer vipType){
        UserPayService userByType = UserPayServiceFactory.getUserByType(vipType);
        return userByType.countFee(orderPrice);
    }


    // 查询已完成订单
    public List<OrderParkDTO> findAll(Integer parkId)throws  Exception{

//        // 1.先从redis缓存获取
//        List<OrderPark> list = (List<OrderPark>)redisTemplate.boundValueOps("orders").get();
//        if(list != null && list.size() > 0){
//            System.err.println("从缓存中获取...");
//            return list;
//        }

//        // 2.缓存中没有,查数据库
//        list = orderParkMapper.findAll(parkId);
//        if( list == null || list.isEmpty()){
//            // 把空值放入缓存
//            redisTemplate.boundValueOps("orders").set(list,30,TimeUnit.SECONDS);
//            System.err.println("....从库中查询无数据,缓存返回空....");
//        }else {
//            redisTemplate.boundValueOps("orders").set(list,30, TimeUnit.MINUTES);
//            System.out.println("....从数据库中查询....");
//        }

        return orderParkMapper.selectAll(parkId);
    }

    /** 导出Excel **/
    public void exportExcel(Integer parkid, HttpServletResponse response)throws Exception {
        /** 查询要导出的数据 */
        List<OrderParkDTO> dtoList = orderParkMapper.selectAll(parkid);
        ServletOutputStream outputStream = response.getOutputStream();
        ExcelWriter writer = new ExcelWriter(outputStream,ExcelTypeEnum.XLSX,true);

        /** 文件名 postman测试文件名会乱码,浏览器测试正常 */
        String fileName = FileUtils.encodeDownloadFilename("订单信息",request.getHeader("user-agent"));

        /** 设置sheet 1代表sheet1, 0代表从第几行开始读取数据，行号最小值为0(表头数据) */
        Sheet sheet = new Sheet(1,0,OrderParkDTO.class);
        sheet.setSheetName("sheet1");

        /** 设置响应头和类型 */
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-disposition","attachment;filename="+fileName + ".xlsx");

        /** 将数据模型写入Excel */
        writer.write(dtoList,sheet);
        writer.finish();

        /** 关闭输出流 */
        outputStream.close();
    }


    /** 下载模板 */
    public void downloadTemplate(HttpServletResponse response) throws Exception{
        ServletOutputStream outputStream = response.getOutputStream();
        ExcelWriter writer = new ExcelWriter(outputStream,ExcelTypeEnum.XLSX,true);
        String filename = FileUtils.encodeDownloadFilename("员工基本信息",request.getHeader("user-agent"));
        Sheet sheet = new Sheet(1,0,ExcelModel.class);
        sheet.setSheetName("sheet1");
        /** 设置响应头和类型 */
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-disposition","attachment;filename="+ filename + ".xlsx");
        /** 将数据模型头部信息写入Excel */
        List<ExcelModel> dtoList = Lists.newArrayList();
        writer.write(dtoList,sheet);
        writer.finish();
        /** 关闭输出流 */
        outputStream.close();
    }

    /**
     * 生成秒杀订单
     * @param productId
     * @param userId
     */
    @Transactional
    public OrderPark createOrder(String productId, Integer userId) {
        // 用Redis原子操作, 逐个减内存中的剩余库存

        // 填充订单信息
        OrderPark orderPark = new OrderPark();
        orderPark.setCarId(1344686);
        orderPark.setParkPrice(new BigDecimal(100));
        orderParkMapper.insert(orderPark);
        String skillKey = getLoginUser().getUserId() + "_" + productId;
        // 下单成功放入缓存方便查询
        redisTemplate.boundValueOps(skillKey).set(orderPark);
        return orderPark;
    }

    // 模拟当前登录用户
    public UserDTO getLoginUser(){
        UserDTO userDTO = new UserDTO();
        userDTO.setUserPhone("18668729211");
        userDTO.setIdCard("1644846");
        return userDTO;
    }

    public static void main(String[] args) throws Exception {
        CompletableFuture<Long> completableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                // 模拟延时3秒
                Thread.sleep(3000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 异步模拟rpc查询有效期
            return getExpireTime();
        });

        // 此处会一直阻塞等待(3秒)completableFuture 结果返回
        Long expireTime = completableFuture.get();

        Order order = new Order();
        order.setNo("20230414864635");
        order.setPrice(new BigDecimal("12.88"));
        order.setProductId(1256L);
        order.setExpireTime(expireTime);

        //
//        ServiceLoader<AnimalSpi> load = ServiceLoader.load(AnimalSpi.class);
//        for (AnimalSpi spi : load) {
//            spi.call();
//        }
    }

    private static Long getExpireTime() {
        return 1346464655L;
    }
    private static LimitRulesDto get(ReginDto dto) {
        Long pid = dto.getProvinceId(); // 买家省id
        Long cityId = dto.getCityId(); // 买家市id
        List<LimitRulesDto> list = getLimitAreas();
        for (LimitRulesDto rulesDto : list) { // 意向商品规则省市集合
            Long cid = rulesDto.getCityId();
            if (pid.equals(rulesDto.getProvinceId())){
                if (cityId.equals(cid) || cid == null){
                    return rulesDto;
                }
            }
        }
        return new LimitRulesDto(">>>>>>>> 不受限制的 <<<<<<<");
    }

    private static List<LimitRulesDto> getLimitAreas() {
        List<LimitRulesDto> list = new ArrayList<>();

        // 浙江省-杭州市
        LimitRulesDto dto = new LimitRulesDto();
        dto.setProvinceId(23l);
        dto.setCityId(10l);
        dto.setName("浙江省-杭州市");
        list.add(dto);

        // 浙江省-宁波市
        LimitRulesDto dto2 = new LimitRulesDto();
        dto2.setProvinceId(23l);
        dto2.setCityId(15l);
        dto2.setName("浙江省-宁波市");
        list.add(dto2);

        // 江西省
        LimitRulesDto dto1 = new LimitRulesDto();
        dto1.setProvinceId(12l);
        dto1.setName("江西省");
        list.add(dto1);

        // 广东省
        LimitRulesDto dto3 = new LimitRulesDto();
        dto3.setProvinceId(52l);
        dto3.setName("广东省");
        list.add(dto3);

        return list;
    }
}
